package com.yangrd.helper.crudhelper.api;

import com.alibaba.fastjson.JSONObject;
import com.yangrd.helper.crudhelper.common.AmisPage;
import com.yangrd.helper.crudhelper.common.Result;
import com.yangrd.helper.crudhelper.core.crud.page.CrudPage;
import com.yangrd.helper.crudhelper.core.crud.page.CrudPageInitService;
import com.yangrd.helper.crudhelper.core.crud.page.CrudPageRepository;
import com.yangrd.helper.crudhelper.core.crud.page.DomainMappingManager;
import com.yangrd.helper.crudhelper.core.crud.page.impl.StringCrudPage;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * description: CrudPageHelper
 *
 * @author: yangrd
 * @date: 2020/9/14
 * @version: 1.0
 */
@RequiredArgsConstructor


@RestController
@RequestMapping("crud-page")
public class CrudPageController {

    private final CrudPageRepository crudPageRepository;

    private final DomainMappingManager domainMappingManager;

    private final CrudPageInitService crudPageInitService;

    @PostMapping("/gen")
    public Result gen(@RequestBody List<String> domains) {
        domains.stream().map(this::toDomainClass).forEach(domainClass -> {
            crudPageInitService.refresh(domainClass);
        });
        return Result.success();
    }

    @GetMapping("/{domain}")
    public CrudPage get(@PathVariable String domain) {
        return crudPageRepository.get(toDomainClass(domain)).orElseThrow(RuntimeException::new);
    }

    @GetMapping("/{domain}/config")
    public Result<String> config(@PathVariable String domain) {
        return Result.success(crudPageRepository.get(toDomainClass(domain)).map(CrudPage::getConfig).orElseThrow(RuntimeException::new));
    }

    @PutMapping("/{domain}")
    public Result<CrudPage> update(@PathVariable String domain, @RequestBody JSONObject config) {
        crudPageRepository.put(toDomainClass(domain), StringCrudPage.of(domain, config.getJSONObject("config").toJSONString()));
        return Result.success();
    }

    @DeleteMapping
    public Result<?> delete(@RequestParam("ids") List<String> ids) {
        ids.forEach(domain -> {
            crudPageRepository.delete(toDomainClass(domain));
        });
        return Result.success();
    }

    @DeleteMapping("/{domain}")
    public Result<?> delete(@PathVariable String domain) {
        crudPageRepository.delete(toDomainClass(domain));
        return Result.success();
    }

    @GetMapping
    public Result<AmisPage<CrudPage>> findAll(@RequestParam(defaultValue = "") String name, int page, int perPage, @RequestParam(defaultValue = "id") String orderBy, @RequestParam(defaultValue = "desc") String orderDir) {
        PageRequest pageRequest = PageRequest.of(page - 1, perPage, Sort.by(Sort.Direction.valueOf(orderDir.toUpperCase()), orderBy));
        Page<CrudPage> objectPage = crudPageRepository.findAll(name, pageRequest);
        return Result.success(AmisPage.of(objectPage));
    }


    private Class<?> toDomainClass(String domain) {
        return domainMappingManager.getDomainClass(domain);
    }

}
